namespace EyeOpen.Data.DataAnnotations.Nhibernate
{
	using System;

	using NHibernate;
	using NHibernate.Cfg;
	using NHibernate.Dialect;
	using NHibernate.Mapping.ByCode;
	using NHibernate.Tool.hbm2ddl;

	public class AnnotationsConfiguration
		: IDisposable
	{
		private readonly IInterceptor interceptor;
		private readonly Configuration configuration;
		private readonly ISessionFactory sessionFactory;

		/// <exception cref="ArgumentNullException">interceptor</exception>
		public AnnotationsConfiguration(IInterceptor interceptor, string connectionString, params Type[] types)
		:	this(connectionString, types)
		{
			if (interceptor == null)
			{
				throw new ArgumentNullException("interceptor");
			}

			this.interceptor = interceptor;
		}

		public AnnotationsConfiguration(string connectionString, params Type[] types)
		{
			configuration = new Configuration();

			var mapper = new ModelAnnotationsMapper();

			mapper.Map(types);

			configuration.DataBaseIntegration(
				c =>
					{
						c.Dialect<MsSql2008Dialect>();
						c.ConnectionString = connectionString;
						c.KeywordsAutoImport = Hbm2DDLKeyWords.AutoQuote;
						c.SchemaAction = SchemaAutoAction.Create;
					});

			var mapping = mapper.CompileMapping();

			var xmlMapping = mapping.AsString();

			configuration.AddMapping(mapping);

			sessionFactory = configuration.BuildSessionFactory();
		}

		public void CreateSchema()
		{
			new SchemaExport(configuration)
				.Create(null, true);
		}

		public ISession OpenSession()
		{
			return
				interceptor == null ? 
					sessionFactory.OpenSession() : 
					sessionFactory.OpenSession(interceptor);
		}

		public void Dispose()
		{
			sessionFactory.Dispose();
		}
	}
}